package com.wasu.sdk_ott.service

import android.app.AlarmManager
import android.app.PendingIntent
import android.app.Service
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.os.SystemClock
import android.text.TextUtils
import android.util.Log
import com.alibaba.fastjson.JSONObject
import com.wasu.sdk_ott.http.live.IPLIVE_CACHE_CHANNEL_KYE
import com.wasu.sdk_ott.http.live.IPLIVE_CACHE_PROGRAM_ALLDAY_KYE
import com.wasu.sdk_ott.http.live.IpLiveLoader
import com.wasu.sdk_ott.http.live.WASU_BOU_EVENT_CHANGED
import com.wasu.sdk_ott.http.live.WASU_EP_CHI_CHANGED
import com.wasu.sdk_ott.http.live.WASU_EP_TODAY_CHANGED
import com.wasu.sdk_ott.provider.LIVE_VERSION_CONTENT_URI
import com.wasu.sdk_ott.provider.VERSION_DB_INTERFACE
import com.wasu.sdk_ott.provider.VERSION_DB_VERSION_NUM
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers

/**
 * <p>------------------------------------------------------
 * <p>Copyright (C) 2020 wasu company, All rights reserved.
 * <p>------------------------------------------------------
 * <p> 查询直播管理系统分组频道和节目单版本号
 * <p>
 *
 * @author Created by zhangmz
 * @date on 2023/9/26
 */
object LiveVersionHelper {

    const val VERSION_TAG = "live_version"

    /**
     * 轮询查询间默认隔时间 1分钟
     */
    private var queryIntervalTime = 5 * 60 * 1000

    /**
     * 创建闹钟类，用来计时
     */
    private var alarmManager: AlarmManager? = null

    /**
     * 创建心跳延迟启动意图，全局变量保存，用来取消使用
     */
    private var pendingIntent: PendingIntent? = null

    /**
     * 订阅结果，用来结束资源
     */
    private var disposable: Disposable? = null

    /**
     * 开启服务
     */
    fun startService(context: Context){
        if (alarmManager == null){
            alarmManager = context.getSystemService(Service.ALARM_SERVICE) as? AlarmManager
        }
        if (pendingIntent == null){
            pendingIntent = PendingIntent.getService(
                context,
                0,
                Intent(context, LiveVersionService::class.java),
                PendingIntent.FLAG_IMMUTABLE
            )
        }
        Log.e(VERSION_TAG, "start query version service, queryIntervalTime:$queryIntervalTime")
        alarmManager?.setExact(
            AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + queryIntervalTime,
            pendingIntent
        ) ?: Log.e(VERSION_TAG, "restartVersionService, alarmManager can not be null")
    }

    /**
     * 停止服务
     */
    fun stopService(context: Context){
        if (alarmManager == null || pendingIntent == null){
            Log.e(VERSION_TAG, "alarm manager start not yet")
            return
        }
        context.stopService(Intent(context, LiveVersionService::class.java))
        alarmManager?.cancel(pendingIntent) ?: Log.e(VERSION_TAG, "cancelVersionService, alarmManager can not be null")
    }

    /**
     * 解析版本号信息
     * @param verJson 服务端原生json
     */
    fun analysisLiveVersion(context: Context?, verJson: String){
        runCatching {
            val jsonObject = JSONObject.parseObject(verJson)
            val cycle = if ((jsonObject.containsKey("cycle")) && jsonObject.getString("cycle").isNotEmpty()) jsonObject.getInteger("cycle") else -1
            if (cycle != -1) queryIntervalTime = cycle * 1000
            Log.e(VERSION_TAG, "queryIntervalTime:$queryIntervalTime; cycle:$cycle")

            insertOrUpdateVersion(context, jsonObject)
        }.onFailure {
            it.printStackTrace()
            Log.e(VERSION_TAG, "analysisLiveVersion, error:$it")
        }
    }

    /**
     * 更新或者插入版本信息
     * @param versionJson 盘本号请求结果
     */
    private fun insertOrUpdateVersion(context: Context?, versionJson: JSONObject){
        if (disposable?.isDisposed == false){ disposable?.dispose() }
        disposable = Observable.create<String> { source ->
            val sb = StringBuffer("")

            val chVersion: Int = if ((versionJson.containsKey("chVersion")) && versionJson.getString("chVersion").isNotEmpty()) versionJson.getInteger("chVersion") else -1
            val chSaveVersion = queryLiveVersion(context, "chVersion")
            Log.v(VERSION_TAG, "insertOrUpdateVersion, chVersion:$chVersion; chSaveVersion:$chSaveVersion")
            if (updateVersionToDb(context, "chVersion", chVersion, chSaveVersion)){
                sb.append("chVersion").append(":")
            }

            val eTodayVersion: Int = if ((versionJson.containsKey("eTodayVersion")) && versionJson.getString("eTodayVersion").isNotEmpty()) versionJson.getInteger("eTodayVersion") else -1
            val eTodaySaveVersion = queryLiveVersion(context, "eTodayVersion")
            Log.v(VERSION_TAG, "insertOrUpdateVersion, eTodayVersion:$eTodayVersion; eTodaySaveVersion:$eTodaySaveVersion")
            if (updateVersionToDb(context, "eTodayVersion", eTodayVersion, eTodaySaveVersion)){
                sb.append("eTodayVersion").append(":")
            }

            val eVersionJson = versionJson.getJSONObject("eVersion")
            eVersionJson?.keys?.forEach { key ->
                val value: Int = if ((eVersionJson.containsKey(key)) && eVersionJson.getString(key).isNotEmpty()) eVersionJson.getInteger(key) else -1
                // 已经保存的指定类型的版本号，-1表示没有保存过，缓存是空
                val saveVerNum = queryLiveVersion(context, key)
                Log.v(VERSION_TAG, "analysisLiveVersion, key:$key; value:$value; saveVerNum:$saveVerNum")

                if (updateVersionToDb(context, key, value, saveVerNum)){
                    sb.append(key).append(":")
                }
            }
            source.onNext(sb.toString())
            source.onComplete()
        }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe{ ver ->
                var versionName = ver
                if (versionName.contains("chVersion")){
                    IpLiveLoader().queryChannelGroupAsync(strategy = "1", defaultKey = IPLIVE_CACHE_CHANNEL_KYE, success = {
                        sendBroadcastLiveVersion(context, "chVersion")
                    })
                }
                versionName = versionName.replace("chVersion:".toRegex(), "")
                if (versionName.contains("eTodayVersion")){
                    IpLiveLoader().queryProgramListAsync(type = "1", strategy = "5", defaultKey = IPLIVE_CACHE_PROGRAM_ALLDAY_KYE, success = {
                        sendBroadcastLiveVersion(context, "eTodayVersion")
                    })
                }
                versionName = versionName.replace("eTodayVersion:".toRegex(), "")
                if (TextUtils.isEmpty(versionName)){
                    return@subscribe
                }
//                val defaultKey = "${IPLIVE_CACHE_PROGRAM_KYE}_$ver"
//                IpLiveLoader().queryProgramListAsync(type = "2", channelId = ver, strategy = "1", defaultKey = defaultKey, success = {
//                    sendBroadcastLiveVersion(context, ver)
//                })
                sendBroadcastLiveVersion(context, versionName)
            }
    }

    /**
     * 查询指定类型版本号
     * @param verName chVersion|eTodayVersion 等指定版本名称，节目单的是 eVersion 下json的key
     */
    private fun queryLiveVersion(context: Context?, verName: String): Int{
        var cursor: Cursor? = null
        var versionNum = -2
        try {
            cursor = context?.contentResolver?.query(
                LIVE_VERSION_CONTENT_URI,
                arrayOf(VERSION_DB_INTERFACE, VERSION_DB_VERSION_NUM),
                "${VERSION_DB_INTERFACE}=?",
                arrayOf(verName),
                null
            )?.apply {
                if (moveToFirst()){
                    val index = getColumnIndex(VERSION_DB_VERSION_NUM)
                    if (index >= 0){ versionNum = getInt(index) }
                }
            }
        }catch (e: Exception){ e.printStackTrace() }
        finally {
            cursor?.close()
        }
        return versionNum
    }

    /**
     * 根据是否保存版本号，判断插入数据库还是更新
     */
    private fun updateVersionToDb(context: Context?, key: String, value: Int, saveValue: Int): Boolean{
        if (saveValue == -2){
            context?.contentResolver?.insert(LIVE_VERSION_CONTENT_URI, ContentValues().apply {
                put(VERSION_DB_INTERFACE, key)
                put(VERSION_DB_VERSION_NUM, value)
            })
            return false
        }
        if (value != saveValue){
            context?.contentResolver?.update(LIVE_VERSION_CONTENT_URI, ContentValues().apply {
                put(VERSION_DB_VERSION_NUM, value)
            }, "${VERSION_DB_INTERFACE}=?", arrayOf(key))
            return true
        }
        return false
    }

    /**
     * 发送广播到body
     * @param verKey 匹配哪个接口版本号变化，确认action，更新节目单，这个值就是频道id
     */
    fun sendBroadcastLiveVersion(context: Context?, verKey: String){
        val action = when(verKey){
            "chVersion" -> "${WASU_BOU_EVENT_CHANGED}${context?.packageName}"
            "eTodayVersion" -> "${WASU_EP_TODAY_CHANGED}${context?.packageName}"
            else -> "${WASU_EP_CHI_CHANGED}${context?.packageName}"
        }
        Log.v(VERSION_TAG, "sendBroadcastLiveVersion, action:$action; context:$context")
        context?.sendBroadcast(Intent().apply {
            putExtra("chId", verKey)
            setAction(action)
        })
    }

}